/////////////
//	CBCombo.cpp		:	v0010
//	Written by		:	Li Haijun
//	Compiler		:	Microsoft Visual C++ 4.0 & DirectX
//	Library			:	DDraw.Lib
//	Copyright (C)	:	1996 WayAhead Corporation 
//	v0010			:	Dec.9.1996
/////////////
// implementation file

// This file provide basic interfaces for deal with combo-box of interface 
//////////////////////////////

#include "stdafx.h"
#include <stdio.h>

#include <ddraw.h>

#include "Assert.h"
#include "DDCompo.h"
#include "DsApi.h"	// sound
#include "CBDraw.h"

#include "DDList.h"
#include "Marco.h"
#include "DDCombo.h"

////////////////////////////
#include "l_allbmp.h"
extern char	bmpfilename[30];
extern char	listfilename[30];
/////////////////////////////////////

/////////////////////////////////////
//	to restore all combo's pointer
class	CDDComboBox	*	pAllComboBox[MAX_COMBOBOX];
class	CDDComboBox *	pCurrentComboBox = NULL;	// a pointer point to the current combo
int		nCurrentComboBoxState;	// current Combo-Box's state,0-none,1-up,2-down,3-focus,4-disable

//constructor
CDDComboBox::CDDComboBox()
{
	m_pShelterSurface = NULL;

	m_nFileNameId = NONE;
	m_ShowString[0] = '\0';
	m_szOneBitmap.cx = 0L;
	m_szOneBitmap.cy = 0L;

	m_rTotal.left	= 0L;
	m_rTotal.top	= 0L;
	m_rTotal.right	= 0L;
	m_rTotal.bottom	= 0L;

	m_rCurrent.left	= 0L;
	m_rCurrent.top	= 0L;
	m_rCurrent.right	= 0L;
	m_rCurrent.bottom	= 0L;

	m_dwX = 0;	m_dwY = 0;

	m_nID = NONE;
	m_nState = COMBOBOX_UP;
	m_nPart = 0;

	m_bEnableSound = TRUE;
}
//constructor
CDDComboBox::~CDDComboBox()
{
	Release();
	m_pShelterSurface = NULL;
	m_nFileNameId = NONE;
	m_nID = NONE;
	m_bEnableSound = TRUE;
}

BOOL CDDComboBox::PreLoad(int FilenameId, int x, int y,
						int OneBitmapWidth/*=0*/, int OneBitmapHeight/*=0*/)
{
	char	fname[20];

	HRESULT			ddrval;
	DDSURFACEDESC	ddsd;

//////////////////////////////////////////////////
	_itoa( FilenameId, fname, 10 );

	class CPicture_imageall picture;

	picture.image_open_compress(bmpfilename);
	picture.image_open_index(listfilename);
	picture.LoadBitmap( &m_BitmapSurface, FilenameId );
	picture.image_close_index();
	picture.image_close_compress();

/////////////////////////////////////////////////////////
	// to set the value of m_FileName
	m_nFileNameId = FilenameId;	//set the member veriable m_FileName
    //
    // get size of surface.
    //
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;

    ddrval = m_BitmapSurface.GetSurface()->GetSurfaceDesc(&ddsd);
	if(ddrval != DD_OK)
		return FALSE;
	m_rTotal.left = m_rTotal.top = 0;
	m_rTotal.right = ddsd.dwWidth;
	m_rTotal.bottom = ddsd.dwHeight;
// to set the value of m_szOneBitmap
	if( (OneBitmapWidth==0)&&(OneBitmapHeight==0) )
	{
		// I assume that all single bitmaps' height is equal to it's width
		if(m_rTotal.bottom > m_rTotal.right)
			m_szOneBitmap.cx = m_szOneBitmap.cy = m_rTotal.right;
		else
			m_szOneBitmap.cx = m_szOneBitmap.cy = m_rTotal.bottom;
		// to set the value of m_rCurrent
		m_rCurrent.left = m_rCurrent.top = 0;
		m_rCurrent.right = m_rCurrent.bottom = m_szOneBitmap.cx;
	}
	else if( OneBitmapWidth * OneBitmapHeight == 0 )
		return FALSE;
	else
	{
		// I assume that all single bitmaps' height is not equal to it's width
		m_szOneBitmap.cx = OneBitmapWidth;
		m_szOneBitmap.cy = OneBitmapHeight;
	}
//to set the value of m_dwX, m_dwY
	m_dwX = x; m_dwY = y;

	SetState(COMBOBOX_UP);

	return TRUE;
}
// to release this combo's pointer
void CDDComboBox::Release()
{
	// to release the surface that record the sheltered background
	if( m_pShelterSurface != NULL )
		m_pShelterSurface->Release();
	// to release the list unit of this combo-box
	m_ListUnit.Release();
	// release the surface that this combo's bitmap used
	m_BitmapSurface.Release();
}
// to set this list's id
void CDDComboBox::SetID(int ID)
{
	m_nID = ID ;	// combo id
}
//	to set the state of this combo-box
void CDDComboBox::SetState(int state)	// let combo up or focus or disable
{
	m_nState = state ;

	if( m_szOneBitmap.cx == m_rTotal.right )
	{
		m_rCurrent.left = m_rTotal.left;
		m_rCurrent.top = m_rTotal.top + m_nState * m_szOneBitmap.cy;
		m_rCurrent.right = m_rCurrent.left + m_szOneBitmap.cx;
		m_rCurrent.bottom = m_rCurrent.top + m_szOneBitmap.cy;
	}
	else
	{
		m_rCurrent.left = m_rTotal.left + m_nState * m_szOneBitmap.cx;
		m_rCurrent.top = m_rTotal.top;
		m_rCurrent.right = m_rCurrent.left + m_szOneBitmap.cx;
		m_rCurrent.bottom = m_rCurrent.top + m_szOneBitmap.cy;
	}
}
//	to get the state of this combo-box
int CDDComboBox::GetState(void)
{
	return m_nState;
}
//to test if the given point on this check-box
BOOL CDDComboBox::OnComboBox( int x, int y)
{
	int	m_nLeftEdge = m_dwX;
	int m_nRightEdge = m_nLeftEdge + (int)m_szOneBitmap.cx;
	int m_nTopEdge = m_dwY;
	int m_nBottomEdge = m_nTopEdge + (int)m_szOneBitmap.cy;

	if( (x >= m_nLeftEdge)&&(x <= m_nRightEdge )
	  &&(y >= m_nTopEdge )&&(y <= m_nBottomEdge) )
		return TRUE;
	else
		return FALSE;
}
// to show the combo box
void CDDComboBox::Show()
{
	POINT	ptDest;

	ptDest.x = m_dwX;
	ptDest.y = m_dwY;
		   
	if( m_nState != COMBOBOX_DISABLE )
	{
		m_BitmapSurface.BltToBack(ptDest, &m_rCurrent);

		RECT	ShowRect;
		ShowRect.left = m_dwX,	ShowRect.top = m_dwY;
		ShowRect.right = m_dwX + m_szOneBitmap.cx;
		ShowRect.bottom = m_dwY + m_szOneBitmap.cy;
		DDC_UpdateScreen( &ShowRect );
	}
}
// to show the drop down list-unit of this combo-box
BOOL CDDComboBox::ShowListUnit()
{
	if(! GetShelterBackGround() )
		return FALSE;
	m_ListUnit.Show();
	return TRUE;
}
// to close the drop down list of this combo-box
void CDDComboBox::CloseListUnit()
{
	for(int i=0; i<MAX_COMBOBOX; i++)
	{
		if( (pAllComboBox[i] != NULL)&&(pAllComboBox[i]->m_pShelterSurface != NULL) )
			pAllComboBox[i]->RestoreShelterBackGround();
	}
}

// to get the sheltered background and record it into a surface
BOOL CDDComboBox::GetShelterBackGround(void)
{
	int		tmp = 0;
	int		width = 0;
	int		height = 0;

	RECT	src;

	for(int i=0; i<MAX_LISTINUNIT; i++)
	{
		if( m_ListUnit.m_pList[i] != NULL )
		{
			tmp++;
		}
	}

	width = m_szOneBitmap.cx;
	height = tmp * m_szOneBitmap.cy;

	src.left	= m_dwX;
	src.top		= m_dwY + m_szOneBitmap.cy;
	src.right	= src.left + m_szOneBitmap.cx;
	src.bottom	= src.top + tmp * m_szOneBitmap.cy;

	m_pShelterSurface = new CDDSurface;
	if(! m_pShelterSurface->Create( width, height ) )
		return FALSE;
	m_pShelterSurface->BltSurface( 0, 0, DD_GetBackBuffer(), &src, DDBLTFAST_NOCOLORKEY );

	return TRUE;
}
// to restore the shelter background when you close the combo-box
void CDDComboBox::RestoreShelterBackGround(void)
{
	int		tmp = 0;
	POINT	ptDest;
	RECT	SrcRect;
	RECT	ShowRect;

	for(int i=0; i<MAX_LISTINUNIT; i++)
	{
		if( m_ListUnit.m_pList[i] != NULL )
			tmp++;
	}

	ptDest.x = m_dwX;
	ptDest.y =  (m_dwY + m_szOneBitmap.cy);

	SrcRect.left = 0;
	SrcRect.top  = 0;
	SrcRect.right  = m_szOneBitmap.cx;
	SrcRect.bottom = tmp * m_szOneBitmap.cy;

	m_pShelterSurface->BltToBack(ptDest, &SrcRect);

	ShowRect.left = m_dwX;
	ShowRect.top = m_dwY + m_szOneBitmap.cy;
	ShowRect.right = ShowRect.left + m_szOneBitmap.cx;
	ShowRect.bottom = ShowRect.top + tmp * m_szOneBitmap.cy;

	DDC_UpdateScreen( &ShowRect );

	m_pShelterSurface->Release();
	m_pShelterSurface = NULL;
}
/////////////////////////////////////////
// to test whether a combo box is clicked ----WM_LBUTTONDOWN
/////////////////////////////////////////
BOOL	LeftButtonDownOnComboBox(int xPos, int yPos)
{
// to define the act when click a list in list-unit of this combo-box
	for( int i=0; i<MAX_COMBOBOX; i++ )
	{
		if( (pAllComboBox[i] != NULL)
		  &&(pAllComboBox[i]->GetState() == COMBOBOX_DOWN) )
		{ 
			for( int j=0; j<MAX_LISTINUNIT; j++ )
			{
				if( (pAllComboBox[i]->m_ListUnit.m_pList[j] != NULL)
				  &&(pAllComboBox[i]->m_ListUnit.m_pList[j]->GetState() != LIST_DISABLE)
				  &&(pAllComboBox[i]->m_ListUnit.m_pList[j]->OnList(xPos, yPos) ) )
				{
					pAllComboBox[i]->m_ListUnit.SetMemberState(LIST_UP);
					// set the just been clicked button's state
					pAllComboBox[i]->m_ListUnit.m_pList[j]->SetState(LIST_DOWN);
					pAllComboBox[i]->m_ListUnit.m_pList[j]->Show();
					pAllComboBox[i]->m_ListUnit.m_nSerialNum = j ; 
	
					pAllComboBox[i]->CloseListUnit();
					pAllComboBox[i]->SetState(COMBOBOX_FOCUS);
					pAllComboBox[i]->Show();
					return TRUE;
				}
			}
		}
	}
	// to define the ace of this combo-box when click this combo-box
	for( int k=0; k<MAX_COMBOBOX; k++ )
	{
		if( pAllComboBox[k] != NULL	)
		{
			if( (pAllComboBox[k]->GetState() != COMBOBOX_DISABLE)
			  &&(pAllComboBox[k]->OnComboBox(xPos, yPos) ) )
			{
				if( pAllComboBox[k]->GetState() == COMBOBOX_FOCUS )
				{
//			MessageBox(hwndGame,"come into LeftButtonDownOnComboBox\n", NULL, MB_OK);
					// to restore the combo-box's state which is in COMBOBOX_DOWN state
					FACE_RestoreAllComboBoxState();
					// set the just clicked combo-box's state and show it
					pAllComboBox[k]->SetState( COMBOBOX_DOWN );
					pAllComboBox[k]->Show();
					// to show the list-unit belong to this combo-box
					pAllComboBox[k]->ShowListUnit();
					// to set the global combo-box's state
					pCurrentComboBox = pAllComboBox[k];
					nCurrentComboBoxState = COMBOBOX_DOWN;
					return TRUE;
				}
				else if( pAllComboBox[k]->GetState() == COMBOBOX_DOWN )
				{
					pAllComboBox[k]->CloseListUnit();
					pAllComboBox[k]->SetState( COMBOBOX_FOCUS );
					pAllComboBox[k]->Show();
					return TRUE;
				}
				else if( pAllComboBox[k]->GetState() == COMBOBOX_UP )
				{
					// to restore the combo-box's state which is in COMBOBOX_DOWN state
					FACE_RestoreAllComboBoxState();
					// set the just clicked combo-box's state and show it
					pAllComboBox[k]->SetState( COMBOBOX_FOCUS );
					pAllComboBox[k]->Show();
					// to set the global combo-box's state
					pCurrentComboBox = pAllComboBox[k];
					nCurrentComboBoxState = COMBOBOX_DOWN;
					return TRUE;
				}
			}
			else if( (pAllComboBox[k]->GetState() == COMBOBOX_DOWN)
			  &&(pAllComboBox[k]->OnComboBox(xPos, yPos) == FALSE) )
			{
				pAllComboBox[k]->CloseListUnit();
				pAllComboBox[k]->SetState( COMBOBOX_UP );
				pAllComboBox[k]->Show();
				return TRUE;
			}
		}
	}
	return	FALSE;
}
///////////////////////////////////////////////////////////
// to test whether cursor is moved on a List ----- WM_ONMOUSEMOVE
///////////////////////////////////////////////////////////
BOOL	MouseMoveOnComboBox(int xPos, int yPos)
{
// to define the act of list-unit in combo-box
	for( int m=0; m<MAX_COMBOBOX; m++ )
	{
		if( (pAllComboBox[m] != NULL)
		  &&(pAllComboBox[m]->GetState() == COMBOBOX_DOWN) )
		{
			for( int n=0; n<MAX_LISTINUNIT; n++ )
			{
			// to up the other one that is in COMBOBOX_FOCUS when move on a different list
				if( (pAllComboBox[m]->m_ListUnit.m_pList[n] != NULL)
					&&(pAllComboBox[m]->m_ListUnit.m_pList[n]->GetState() == LIST_FOCUS )
					&&(!pAllComboBox[m]->m_ListUnit.m_pList[n]->OnList(xPos, yPos) ) )
				{
					// set the just been clicked button's state
					pAllComboBox[m]->m_ListUnit.m_pList[n]->SetState(LIST_UP);
					pAllComboBox[m]->m_ListUnit.m_pList[n]->Show();
				}
			// to focus the combo-box that you just moveon 
				if( (pAllComboBox[m]->m_ListUnit.m_pList[n] != NULL)
					   &&(pAllComboBox[m]->m_ListUnit.m_pList[n]->GetState() == LIST_UP )
					   &&(pAllComboBox[m]->m_ListUnit.m_pList[n]->OnList(xPos, yPos) ) )
				{
					// set the just been clicked button's state
					pAllComboBox[m]->m_ListUnit.m_pList[n]->SetState(LIST_FOCUS);
					pAllComboBox[m]->m_ListUnit.m_pList[n]->Show();
					return TRUE;
				}
			}
			return TRUE;
		}
	}
// to define act of combo-box when mouse move on a combo-box
	for( int i=0; i<MAX_COMBOBOX; i++ )
	{
		if( (pAllComboBox[i] != NULL)
		  &&(pAllComboBox[i]->GetState() != COMBOBOX_DISABLE)
		  &&(pAllComboBox[i]->OnComboBox(xPos, yPos) ) )
		{
			if( pAllComboBox[i]->GetState() == COMBOBOX_UP )
			{
			// to up all the other focus combo-box
				for(int j=0; j<MAX_COMBOBOX; j++)
				{
					if( (pAllComboBox[j] != NULL)
					  &&(pAllComboBox[j]->GetState() ==	COMBOBOX_FOCUS) )
					{
						pAllComboBox[j]->SetState(COMBOBOX_UP);
						pAllComboBox[j]->Show();
					}
				}
				// set the just clicked combo-box's state and show it
				pAllComboBox[i]->SetState( COMBOBOX_FOCUS );
				pAllComboBox[i]->Show();
				// to set the global combo-box's state
				pCurrentComboBox = pAllComboBox[i];
				nCurrentComboBoxState = COMBOBOX_FOCUS;
				return TRUE;
			}
		}
		else if( (pAllComboBox[i] != NULL)
		  &&(pAllComboBox[i]->GetState() == COMBOBOX_FOCUS)
		  &&(pAllComboBox[i]->OnComboBox(xPos, yPos) == FALSE) )
		{
			// set the just clicked combo-box's state and show it
			pAllComboBox[i]->SetState( COMBOBOX_UP );
			pAllComboBox[i]->Show();
			return TRUE;
		}
	}
	return FALSE;
}
////////////////////////////////////////////////////////////////////////////////
void	FACE_DeleteAllComboBox()
{
	for( int i=0; i<MAX_COMBOBOX; i++ )
	{
		if( pAllComboBox[i] != NULL	)
		{
			delete pAllComboBox[i];
			pAllComboBox[i] = NULL;
		}
	}
	return;
}
// to restore all combo-box that in pAllComboBox[MAX_COMBOBOX] to COMBOBOX_UP state
void	FACE_RestoreAllComboBoxState( )
{
	for( int i=0; i<MAX_COMBOBOX; i++ )
	{
		if( (pAllComboBox[i] != NULL)&&(pAllComboBox[i]->GetState() == COMBOBOX_DOWN) )
		{
			pAllComboBox[i]->CloseListUnit();
			pAllComboBox[i]->SetState(COMBOBOX_UP);
			pAllComboBox[i]->Show();
		}
	}
}
////////////// END
